#include <fstream>
#include <iostream>
#include <string>
#include <sstream>

// Function to export a GPIO pin
bool export_gpio(int gpio_line) {
    std::ofstream export_file("/sys/class/gpio/export");
    if (!export_file) {
        std::cerr << "Failed to open export file" << std::endl;
        return false;
    }
    export_file << gpio_line;
    export_file.close();
    return true;
}

bool unexport_gpio(int gpio_line) {
    std::ofstream unexport_file("/sys/class/gpio/unexport");
    if (!unexport_file) {
        std::cerr << "Failed to open unexport file" << std::endl;
        return false;
    }
    unexport_file << gpio_line;
    unexport_file.close();
    return true;
}

// Function to set the direction of a GPIO pin
bool set_gpio_direction(int gpio_line, const std::string& direction) {
    std::ofstream direction_file("/sys/class/gpio/gpio" + std::to_string(gpio_line) + "/direction");
    if (!direction_file) {
        std::cerr << "Failed to open direction file" << std::endl;
        return false;
    }
    direction_file << direction;
    direction_file.close();
    return true;
}

// Function to read the value of a GPIO pin
bool read_gpio_value(int gpio_line, int& value) {
    std::ifstream value_file("/sys/class/gpio/gpio" + std::to_string(gpio_line) + "/value");
    if (!value_file) {
        std::cerr << "Failed to open value file" << std::endl;
        return false;
    }
    value_file >> value;
    value_file.close();
    return true;
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " <operation> [gpio_line] [direction]" << std::endl;
        std::cerr << "Operations: export, set_direction, read_value" << std::endl;
        return 1;
    }

    std::string operation = argv[1];
    int gpio_line = 0;
    if (argc > 2) {
        gpio_line = std::stoi(argv[2]);
    }
    std::string direction;
    if (argc > 3) {
        direction = argv[3];
    }

    if (operation == "export") {
        if (gpio_line == 0) {
            std::cerr << "GPIO line number is required for export operation" << std::endl;
            return 1;
        }
        if (export_gpio(gpio_line)) {
            std::cout << "GPIO " << gpio_line << " exported successfully" << std::endl;
        } else {
            return 1;
        }
    }
    else if (operation == "unexport") {
        if (gpio_line == 0) {
            std::cerr << "GPIO line number is required for unexport operation" << std::endl;
            return 1;
        }
        if (unexport_gpio(gpio_line)) {
            std::cout << "GPIO " << gpio_line << " unexported successfully" << std::endl;
        } else {
            return 1;
        }
    }
    else if (operation == "set_direction") {
        if (gpio_line == 0 || direction.empty()) {
            std::cerr << "GPIO line number and direction are required for set_direction operation" << std::endl;
            return 1;
        }
        if (set_gpio_direction(gpio_line, direction)) {
            // std::cout << "GPIO " << gpio_line << " direction set to " << direction << std::endl;
        } else {
            return 1;
        }
    } else if (operation == "read_value") {
        if (gpio_line == 0) {
            std::cerr << "GPIO line number is required for read_value operation" << std::endl;
            return 1;
        }
        int gpio_value;
        if (read_gpio_value(gpio_line, gpio_value)) {
            // std::cout << "GPIO " << gpio_line << " value: " << gpio_value << std::endl;
            return gpio_value;
        } else {
            return 1;
        }
    } else {
        std::cerr << "Unknown operation: " << operation << std::endl;
        return 1;
    }

    return 0;
}
